/**
 ******************************************************************************
 * @file           : bsp_usart.c
 * @brief          : USART Driver Implementation (STM32H7xx)
 ******************************************************************************
 * @attention
 *
 * USART驱动程序实现文件
 * 提供USART初始化、收发、状态查询等功能
 * 支持printf重定向
 *
 ******************************************************************************
 */

/* Includes ------------------------------------------------------------------*/
#include "./BSP/USART/bsp_usart.h"
#include "./BSP/USART/bsp_usart_config.h"

/* Private includes ----------------------------------------------------------*/
/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/
#define USART_RX_BUF_SIZE       256         /*!< 接收缓冲区大小 */
#define USART_TX_BUF_SIZE       256         /*!< 发送缓冲区大小 */
#define USART_TX_TIMEOUT        1000        /*!< 发送超时时间(ms) */
#define USART_DEFAULT_BAUDRATE  115200      /*!< 默认波特率 */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
static UART_HandleTypeDef sg_usart_handle;                      /*!< USART句柄 */
static uint8_t sg_usart_rx_buffer[USART_RX_BUF_SIZE];           /*!< 接收缓冲区 */
static volatile uint16_t sg_usart_rx_count = 0;                 /*!< 接收数据计数器 */
static volatile USART_State_e sg_usart_state = USART_STATE_IDLE;/*!< USART当前状态 */
static volatile uint8_t sg_usart_initialized = 0;               /*!< 初始化标志 */
static volatile uint8_t sg_usart_rx_complete = 0;               /*!< 行接收完成标志 */

/* Private function prototypes -----------------------------------------------*/
static void usart_gpio_init(void);
static void usart_uart_init(uint32_t baudrate);

/* Private functions ---------------------------------------------------------*/

/**
 * @brief       USART GPIO引脚初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        配置TX/RX引脚
 */
static void usart_gpio_init(void)
{
    GPIO_InitTypeDef gpio_init_struct = {0};
    
    /* 使能GPIO时钟 */
    USART_TX_GPIO_CLK_ENABLE();
    USART_RX_GPIO_CLK_ENABLE();
    
    /* 配置TX引脚 - 复用推挨输出 */
    gpio_init_struct.Pin = USART_TX_GPIO_PIN;
    gpio_init_struct.Mode = GPIO_MODE_AF_PP;
    gpio_init_struct.Pull = GPIO_PULLUP;
    gpio_init_struct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
    gpio_init_struct.Alternate = USART_GPIO_AF;
    HAL_GPIO_Init(USART_TX_GPIO_PORT, &gpio_init_struct);
    
    /* 配置RX引脚 - 复用输入 */
    gpio_init_struct.Pin = USART_RX_GPIO_PIN;
    HAL_GPIO_Init(USART_RX_GPIO_PORT, &gpio_init_struct);
}

/**
 * @brief       USART外设初始化
 *
 * @param[in]   baudrate 波特率
 *
 * @retval      无
 *
 * @note        配置UART参数并使能接收中断
 */
static void usart_uart_init(uint32_t baudrate)
{
    /* 使能UART时钟 */
    USART_UARTx_CLK_ENABLE();
    
    /* 配置UART参数 */
    sg_usart_handle.Instance = USART_UARTx;
    sg_usart_handle.Init.BaudRate = baudrate;
    sg_usart_handle.Init.WordLength = UART_WORDLENGTH_8B;
    sg_usart_handle.Init.StopBits = UART_STOPBITS_1;
    sg_usart_handle.Init.Parity = UART_PARITY_NONE;
    sg_usart_handle.Init.HwFlowCtl = UART_HWCONTROL_NONE;
    sg_usart_handle.Init.Mode = UART_MODE_TX_RX;
    sg_usart_handle.Init.OverSampling = UART_OVERSAMPLING_16;
    
    if (HAL_UART_Init(&sg_usart_handle) != HAL_OK)
    {
        log_e("UART初始化失败");
        return;
    }
    
    /* 配置并使能接收中断 */
    __HAL_UART_ENABLE_IT(&sg_usart_handle, UART_IT_RXNE);
    HAL_NVIC_SetPriority(USART_UARTx_IRQn, 3, 3);
    HAL_NVIC_EnableIRQ(USART_UARTx_IRQn);
}

/* Exported functions --------------------------------------------------------*/

/**
 * @brief       USART初始化
 *
 * @param[in]   baudrate 波特率(如9600, 115200等)
 *
 * @retval      无
 *
 * @note        初始化GPIO、UART和中断
 * @note        初始化成功后自动清空接收缓冲区
 */
void usart_init(uint32_t baudrate)
{
    /* 参数检查 */
    if (baudrate == 0)
    {
        log_w("波特率参数无效，使用默认值: %d", USART_DEFAULT_BAUDRATE);
        baudrate = USART_DEFAULT_BAUDRATE;
    }
    
    /* 初始化GPIO */
    usart_gpio_init();
    
    /* 初始化UART */
    usart_uart_init(baudrate);
    
    /* 清空接收缓冲区和标志 */
    sg_usart_rx_count = 0;
    sg_usart_rx_complete = 0;
    
    /* 设置状态 */
    sg_usart_state = USART_STATE_IDLE;
    
    /* 标记已初始化 */
    sg_usart_initialized = 1;
    
    log_i("USART初始化完成 - 波特率: %lu", baudrate);
}

/**
 * @brief       USART反初始化
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        关闭UART和中断，释放资源
 */
void usart_deinit(void)
{
    if (!sg_usart_initialized)
    {
        return;
    }
    
    /* 禁用UART中断 */
    HAL_NVIC_DisableIRQ(USART_UARTx_IRQn);
    __HAL_UART_DISABLE_IT(&sg_usart_handle, UART_IT_RXNE);
    
    /* 反初始化UART */
    HAL_UART_DeInit(&sg_usart_handle);
    
    /* 清除标志 */
    sg_usart_initialized = 0;
    sg_usart_state = USART_STATE_IDLE;
    
    log_i("USART已反初始化");
}

/**
 * @brief       USART发送数据
 *
 * @param[in]   data 发送数据指针
 * @param[in]   len  发送数据长度(字节)
 *
 * @retval      USART_OK         发送成功
 * @retval      USART_ERROR_PARAM 参数错误
 * @retval      USART_ERROR_TIMEOUT 发送超时
 *
 * @note        阻塞发送
 */
USART_Error_e usart_send(const uint8_t *data, uint16_t len)
{
    HAL_StatusTypeDef status;
    
    /* 参数检查 */
    if (data == NULL || len == 0)
    {
        log_w("发送参数错误: data=%p, len=%d", data, len);
        return USART_ERROR_PARAM;
    }
    
    if (!sg_usart_initialized)
    {
        log_e("USART未初始化");
        return USART_ERROR_PARAM;
    }
    
    /* 设置发送状态 */
    sg_usart_state = USART_STATE_TX;
    
    /* 发送数据 */
    status = HAL_UART_Transmit(&sg_usart_handle, (uint8_t*)data, len, USART_TX_TIMEOUT);
    
    /* 恢复空闲状态 */
    sg_usart_state = USART_STATE_IDLE;
    
    if (status != HAL_OK)
    {
        log_e("发送失败: status=%d, len=%d", status, len);
        return USART_ERROR_TIMEOUT;
    }
    
    log_d("发送成功: %d字节", len);
    return USART_OK;
}

/**
 * @brief       USART发送字符串
 *
 * @param[in]   str 要发送的字符串
 *
 * @retval      USART_OK         发送成功
 * @retval      USART_ERROR_PARAM 参数错误
 * @retval      USART_ERROR_TIMEOUT 发送超时
 *
 * @note        自动计算字符串长度
 */
USART_Error_e usart_send_string(const char *str)
{
    if (str == NULL)
    {
        return USART_ERROR_PARAM;
    }
    
    uint16_t len = 0;
    while (str[len] != '\0' && len < USART_TX_BUF_SIZE)
    {
        len++;
    }
    
    return usart_send((const uint8_t*)str, len);
}

/**
 * @brief       USART接收数据
 *
 * @param[out]  data 接收数据存储指针
 * @param[out]  len  返回接收到的数据长度
 *
 * @retval      USART_OK         接收成功
 * @retval      USART_ERROR_PARAM 参数错误
 *
 * @note        从接收缓冲区复制数据，非阻塞
 * @note        接收完成后自动清空接收缓冲区和行完成标志
 */
USART_Error_e usart_receive(uint8_t *data, uint16_t *len)
{
    uint16_t rx_count;
    
    /* 参数检查 */
    if (data == NULL || len == NULL)
    {
        log_w("接收参数错误: data=%p, len=%p", data, len);
        return USART_ERROR_PARAM;
    }
    
    if (!sg_usart_initialized)
    {
        log_e("USART未初始化");
        *len = 0;
        return USART_ERROR_PARAM;
    }
    
    /* 读取接收计数 */
    rx_count = sg_usart_rx_count;
    *len = 0;
    
    /* 检查是否有数据 */
    if (rx_count == 0)
    {
        return USART_OK;
    }
    
    /* 复制数据 */
    for (uint16_t i = 0; i < rx_count; i++)
    {
        data[i] = sg_usart_rx_buffer[i];
    }
    
    *len = rx_count;
    
    /* 清空接收缓冲区和行完成标志 */
    sg_usart_rx_count = 0;
    sg_usart_rx_complete = 0;
    
    log_d("接收成功: %d字节", *len);
    
    return USART_OK;
}

/**
 * @brief       获取接收数据量
 *
 * @param       无
 *
 * @retval      当前接收缓冲区中的数据量(字节)
 *
 * @note        非阻塞，立即返回
 */
uint16_t usart_get_rx_count(void)
{
    return sg_usart_rx_count;
}

/**
 * @brief       清空接收缓冲区
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        丢弃所有未读取的数据
 */
void usart_flush_rx(void)
{
    sg_usart_rx_count = 0;
    sg_usart_rx_complete = 0;
    log_d("接收缓冲区已清空");
}

/**
 * @brief       获取USART当前状态
 *
 * @param       无
 *
 * @retval      USART_State_e 当前状态
 *
 * @note        用于状态监控和调试
 */
USART_State_e usart_get_state(void)
{
    return sg_usart_state;
}

/**
 * @brief       检查是否有接收数据
 *
 * @param       无
 *
 * @retval      1 有数据
 * @retval      0 无数据
 *
 * @note        快速检查接收缓冲区状态
 */
uint8_t usart_is_rx_ready(void)
{
    return (sg_usart_rx_count > 0) ? 1 : 0;
}

/**
 * @brief       检查是否接收到完整行
 *
 * @param       无
 *
 * @retval      1 接收到完整行(以\r\n结束)
 * @retval      0 未接收到完整行
 *
 * @note        用于USART等需要行缓冲的应用
 */
uint8_t usart_is_line_ready(void)
{
    return sg_usart_rx_complete;
}

/**
 * @brief       打印USART当前状态（用于调试）
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        显示波特率、状态、接收缓冲区等信息
 */
void usart_print_status(void)
{
    const char *state_str[] = {"IDLE", "TX", "RX", "ERROR"};
    
    log_i("USART当前状态:");
    log_i("  初始化状态: %s", sg_usart_initialized ? "已初始化" : "未初始化");
    log_i("  波特率: %lu", sg_usart_handle.Init.BaudRate);
    log_i("  当前状态: %s", state_str[sg_usart_state]);
    log_i("  接收缓冲区大小: %d 字节", USART_RX_BUF_SIZE);
    log_i("  当前接收数据量: %d 字节", sg_usart_rx_count);
    
    if (sg_usart_rx_count > 0)
    {
        log_i("  接收缓冲区内容 (前16字节):");
        for (uint16_t i = 0; i < sg_usart_rx_count && i < 16; i++)
        {
            log_i("    [%d] = 0x%02X ('%c')", i, sg_usart_rx_buffer[i], 
                  (sg_usart_rx_buffer[i] >= 32 && sg_usart_rx_buffer[i] <= 126) ? sg_usart_rx_buffer[i] : '.');
        }
    }
}

/**
 * @brief       UART中断处理函数
 *
 * @param       无
 *
 * @retval      无
 *
 * @note        在中断中将接收数据存入缓冲区
 * @note        检测\r\n标记行接收完成
 * @note        缓冲区满时丢弃新数据并记录错误日志
 */
void USARTx_IRQHandler(void)
{
    uint8_t data;
    static uint8_t last_char = 0;
    
    if (__HAL_UART_GET_FLAG(&sg_usart_handle, UART_FLAG_RXNE) != RESET)
    {
        if (HAL_UART_Receive(&sg_usart_handle, &data, 1, 1) == HAL_OK)
        {
            if (sg_usart_rx_complete)
            {
                return;
            }
            
            if (data == '\n' && last_char == '\r')
            {
                sg_usart_rx_complete = 1;
                sg_usart_state = USART_STATE_IDLE;
            }
            else if (data == '\r' || data == '\n')
            {
                if (sg_usart_rx_count > 0)
                {
                    sg_usart_rx_complete = 1;
                    sg_usart_state = USART_STATE_IDLE;
                }
            }
            else
            {
                if (sg_usart_rx_count < USART_RX_BUF_SIZE - 1)
                {
                    sg_usart_rx_buffer[sg_usart_rx_count++] = data;
                    sg_usart_state = USART_STATE_RX;
                }
                else
                {
                    log_w("接收缓冲区溢出，重置");
                    sg_usart_rx_count = 0;
                    sg_usart_rx_complete = 0;
                    sg_usart_state = USART_STATE_ERROR;
                }
            }
            
            last_char = data;
        }
    }
}
